home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
docs
/
mod2txt
/
chap6.txt
< prev
next >
Wrap
Text File
|
1987-03-25
|
26KB
|
586 lines
Chapter 6 - Arrays, Types, and Constants
Load the program named ARRAYS.MOD and we will go right
to our first example of an array. An array is simply a list
made up of several of the same type of element. Notice the
VAR definition in the sample program and specifically the
variable named "Automobiles". The reserved word ARRAY
followed by the square brackets with a range of numbers
contained within them is the proper way to define an array
of, in this case, CARDINAL type variables. This defines 12
different CARDINAL type variables, each of which is capable
of storing one CARDINAL number. The names of the twelve
variables are given by Automobiles[1], Automobiles[2], ...
Automobiles[12]. The variable name is "Automobiles" and the
array subscripts are the numbers 1 through 12. The
variables are true CARDINAL type variables and can be
assigned values, or they can be used in calculations or in
nearly anyplace in a program where it is legal to use a
CARDINAL type variable. One place they cannot be used is as
the index for a FOR loop since a simple variable type is
required there.
WHAT GOOD ARE ARRAYS?
Notice lines 10 through 12 of the program. In these
lines, each of the 12 variables is assigned a value. When
"Index" is 1, then "Automobiles[1]" is assigned 11, then
when "Index" is 2, "Automobiles[2]" is assigned 12, etc.
If the 12 variables were defined as 12 separate
variables of whatever names we chose for them, we could not
assign them values in a loop but would have to assign each
one independently. In this instance, we are generating
nonsense data but in a real program, this loop could be
reading in a series of data from a file such as would be
done with a database. The advantage of the array should be
very clear, especially if we were to change the array limits
to several thousand elements.
The statement in line 13 assigns a value to one of the
elements at random to illustrate the method. Notice that
the 7th element of the array named "Automobiles" is assigned
the value of 54. The address of this data is therefore the
variable name "Automobiles[7]" and the data contained in
that address is 54. We have therefore assigned values to
the 12 variables by a nonsensical but known scheme, and now
we can use the 12 variables in any way that is legal within
Modula-2.
The next loop causes the 12 values to be displayed on
the monitor in a neat orderly fashion. In line 20 we
display the index of the variable in question, and in line
22, we display the actual variable. Keep in mind that the
Page 37
Chapter 6 - Arrays, Types, and Constants
index could have been INTEGER and still be used to display
an array of type CARDINAL provided we defined "Index" as an
integer and always used it as such. Spend enough time with
this program so that you thoroughly understand it, then
compile and run it.
WHAT ABOUT AN ILLEGAL SUBSCRIPT?
Modula-2 does very strong "type checking" and limit
checking. If, in the above program, you tried to assign a
value to "Automobiles[13]", which doesn't exist, a run time
error would be generated and the program would cease. This
is one of the advantages of Modula-2 over some of the older
programming languages. Some compilers have the ability to
enable or disable this feature.
MULTIPLY DIMENSIONED ARRAYS
Load the file named ARRAYS2.MOD for an example of a
program with two-dimensional arrays. In this program, the
VAR section contains the "Checkerboard" variable which is
defined as an 8 element ARRAY in which each element is an 8
element ARRAY, therefore being an 8 by 8 square ARRAY. Each
element is capable of storing one CARDINAL type variable.
The variable "Value" is defined the same way except that the
method of definition is slightly different. The two methods
result in the same type and number of variables.
In lines 11 through 16 we have two nested FOR loops.
The outer loop causes "Index" to count from 1 to 8 and for
each value of "Index", the variable "Count" counts through
the values 1 to 8 also. The net result is that we evaluate
the assignments in lines 13 and 14 once for each possible
combination of "Index" and "Count". For each combination,
we assign some nonsense data to "Checkerboard" then use the
result of that calculation to assign some nonsense data to
the variable "Value". The purpose here is to illustrate the
method of using the double subscripted variables. Next we
display the entire matrix of "Checkerboard". The loops
cause 8 values to be displayed on one line so that the
entire matrix is displayed on only 8 lines. You should
study this logic because you will find output sequences like
this to be very valuable.
CHANGING A FEW OF THE VALUES
In line 27 and following we change a few of the values
at random for illustrative purposes. Since "Value[3,6]" is
assigned the value of 3, it can be used as one of the
subscripts of the next line and in fact it is. This would
be a rather sloppy programming style but it is a good
Page 38
Chapter 6 - Arrays, Types, and Constants
illustration of what can be done. Finally using the same
technique as that for "Checkerboard", the "Value" matrix is
displayed.
HOW MANY SUBSCRIPTS CAN BE USED?
There is no limit as to how many subscripts can be used
in Modula-2 by definition, but there is a practical limit of
somewhere in the range of 3 or 4. If you use too many, you
will very quickly get confused and lose control of what the
program is supposed to be doing. I have never seen more
than 3 subscripts used in any programming language, and very
few instances of more than two. Let the problem definition
be your guide.
This program was pretty straightforward, and it is time
for you to compile and run it.
THE TYPE DECLARATION
Load the program named TYPES.MOD for a new topic that
you will use often, especially in large programs. At the
top of the listing we have a group of TYPE declarations.
The first line defines "ArrayDef" as a new TYPE definition
that can be used in the same way you would use INTEGER or
any of the other simple type definitions. In line 12, the
variable named "Stuff" is defined as a variable of type
"ArrayDef", and since "ArrayDef" is a 14 element ARRAY, then
"Stuff" is a 14 element array of INTEGER. It seems like we
didn't save anything and in fact we added a few keystrokes
to the program in order to do this. If you look at line 13
you will see that we have also defined "Stuff2" as the same
type of array. We have, in fact, defined them to be "type
compatible" which will be very important when we get to the
program itself.
Continuing down the list of TYPE declarations, we
define a TYPE with 28 characters, then a TYPE with 60 real
variables, and another with 6 BOOLEAN variables. The next
TYPE consists of 12 variables of TYPE "DogFood" which is
itself a TYPE of 6 BOOLEANS, resulting in a TYPE consisting
of 6 times 12 = 72 BOOLEANS. It is possible to continue
building up TYPE definitions like this indefinitely, and as
you build up applications, you will find yourself building
up rather complex TYPE declarations and having a clear
picture of how they go together because it is your solution
to a problem. The last TYPE to be defined is that named
"Boat" which has exactly the same size and characteristics
as "Airplane". We will see shortly that there is a
difference in these two definitions.
Page 39
Chapter 6 - Arrays, Types, and Constants
HOW DO WE USE ALL OF THIS?
In the VAR part of the definition part of the program,
we declare some variables, two simple types and some of the
types we defined above. In the program part, we assign some
values to the 72 variables making up the "Puppies" matrix
and the 72 variables making up the "Kitties" matrix. All of
the elements of "Stuff" are then assigned nonsense values.
The really interesting statement comes in line 30 where we
say "Stuff2 := Stuff;". In this simple statement, all 14
values stored in "Stuff" are copied into the 14
corresponding elements of "Stuff2" without using a loop.
This is possible because the two variables are TYPE
compatible, they have the same TYPE definition. If you
study the definitions above, you will see that "Stuff3" is
of the same number and range of elements and is composed of
the same type of elements, namely INTEGER, as "Stuff" but
they are not TYPE compatible because were not defined with
the same TYPE definition statement. In like manner, even
though "Puppies" and "Kitties" are identical in type, they
are not TYPE compatible.
You have the ability, through careful assignment of
variables, to avoid certain kinds of programming errors. If
certain variables should never be assigned to each other, a
careful selection of types can prevent it. Suppose for
example that you have a program working with peaches and
books. You would never want to copy a matrix of peaches to
one defining books, it just wouldn't make sense. Those two
matrices should be defined with different type declarations
even though they may be identical in size.
Compile and run this program, even though it will
result in no output, then move the comment delimiter in line
31 to a position following the assignment statement and see
if it does give you a TYPE incompatibility error.
DEFINING A CONSTANT
Load the program named CONSTANT.MOD for a definition of
the constant as used in Modula-2. We will finally keep the
promise made when we studied LOOPDEMO in chapter 4. The new
reserved word CONST is used to define a constant for use in
the program. The constant "MaxSize" can be used anywhere in
the program that it is desired to use the number 12, because
they are in fact identical. Two additional CONST values are
defined for illustrative purposes only. In the TYPE
declaration section we use the constant "MaxSize" to define
two types, then use them to define several variables.
Page 40
Chapter 6 - Arrays, Types, and Constants
In the program there is one FOR loop using the same
constant "MaxSize" as the upper limit. It doesn't seem to
be too useful yet, but suppose your boss came to you and
said to change the program so that it handled 142 cases
instead of 12. The way the program is written, you would
only have to change the value of the constant, recompile,
and you would be done. If you had used the number 12
everywhere, you would have to replace every 12 with the new
number, 142, being careful not to change the one in line 21
which is a different kind of 12. Of course even that would
not be too difficult in such a simple program, but in a
program with 5000 lines of code, one simple change could
take a week.
Compile and run this program.
THE OPEN ARRAY IN A PROCEDURE
Load and display the program named ARAYPASS.MOD for an
example of a program with arrays being passed to a
procedure. Notice how the procedures are formatted. The
rows of asterisks make them really stand out and easy to
find. You will develop your own personal style of
formatting in a way that is clear and easy to follow for
you.
The two procedures in this program are identical except
for the way the arrays are passed to them. In the first
procedure named "AddNumbers", the variable named "Donkey" is
passed the array by using the same type which was used to
define one of the arrays. The procedure merely adds the
values of the elements of the array passed to it and writes
the result out to the monitor. The way it is written, it is
only capable of adding arrays that are indexed from 10 to
15. Any other array will cause a "type incompatible" error.
This is simply called passing an array to the procedure.
The second procedure named "GenAddNumbers" has its
input array defined as an "ARRAY OF CARDINAL" with no limits
stated. This procedure can add all of the variables in any
CARDINAL array regardless of the range of its subscripts.
The lower subscript will always be defined as zero within
this type of procedure, and the upper limit of the array can
be found with the predefined procedure "HIGH". It is used
as shown in the example. The first time this procedure is
called in the main program, it is called with the variable
"SizeOne". In the procedure, the array subscripts for
"Donkey" will be 0 through 5. When the variable named
"SizeTwo" is the array sent to the procedure, then "Donkey"
will have the limits of 0 and 218. The second procedure
Page 41
Chapter 6 - Arrays, Types, and Constants
definition method is therefore more general. This is called
passing an "open array" to the procedure.
WHICH ONE SHOULD I USE?
There will be times when you wish to use the general
case for passing a parameter, the "open array". A good
example is the procedure named "WriteString" that we have
been using in this tutorial. It would be a bit cumbersome
if we were only allowed to pass a 10 character string to it
each time. Since it can accept a string of any length, it
is evidently defined with an "ARRAY OF CHAR" in its header.
(We will see in a later chapter that this particular
procedure is exactly that, a procedure that someone has
thoughtfully programmed for you. You only need to tell the
system where it can be found using the IMPORT statement.)
There will likewise be times when you will desire to
use the more specific method of definition. If you are
using a lot of arrays and have a specific operation that
needs to be done to only a few arrays that have a common
definition, you would be wise to use this method. The
computer could then tell you if you tried to use the
procedure on an array that it was not intended for. This is
making wise use of the type checking available in the
computer.
HANDLING STRINGS IN MODULA-2
Load the last file for this chapter, STRINGEX.MOD for
an example of using strings in Modula-2. This program is
the first program to deviate from the standard library as
defined by Niklaus Wirth. When he defined the language, he
suggested several library procedures that should be
available in every Modula-2 compiler and most compiler
writers have followed his suggestions quite closely. He
failed to define a standard library for the string handling
procedures. There is therefore some freedom for each
compiler writer to define the string handling routines in
any way he pleases. Most however, have followed at least a
resemblance to a standard, so the procedure calls are very
similar from compiler to compiler. It may be necessary for
you to modify this file to suit your particular compiler.
The COMPILER.DOC file on your distribution disk has comments
for modifications needed for several compilers, but if yours
is not listed, it will be up to you to make the required
modifications to the source file.
A complete description of the libraries and what they
are will be given in chapter 8.
Page 42
Chapter 6 - Arrays, Types, and Constants
BACK TO THE PROGRAM ON YOUR DISPLAY
The first thing that is different here is the addition
of another IMPORT statement in line 10, this one importing
procedures from the module named "Strings". This is the
module containing the procedures which we will need in this
program. A string is an array of type CHAR, each element of
the array being capable of storing one character. Thus an
array of CHAR type elements is capable of storing a word, a
sentence, a paragraph, or even a whole chapter, depending on
how big the array is. Using the example on your screen, we
will learn how to manipulate text data.
One additional feature of the example program will be
found on line 24. In this line the "WriteString" procedure
is used in a way we have not used as yet. Instead of having
an expression in quotes, it has the name of a variable
within its parentheses. It will display whatever characters
are stored in the string named "stuff" defined by the "ARRAY
OF CHAR". So if we learn how to get a string of characters
stored in a variable of type "string", we can display
anything on the monitor that we can generate internal to the
computer.
According to the definition of Modula-2, a string is an
ARRAY OF CHAR with a 0 as a terminator. We will get more
familiar with strings as we continue our study.
SOME NEW STRING PROCEDURES
The first line of the program itself, line 34, contains
a string assignment. In this case, we are telling the
system to copy the constant "ABCDEFGHIJKL" into the variable
named "Horse". The array into which you are copying must
begin at index 0 in order for this to work because all
character constants are, by definition, started at zero.
The variable "Horse", which only contains room for 12
characters will only receive the first 12 characters of the
constant. The procedure "Display" is called with Horse as
the variable and the variable is displayed between
parentheses for clarity of understanding, and the 12
characters of the variable are displayed in their ASCII
equivalent. When you finally run this program, compare some
of the values to the ASCII table that is included with the
DOS documentation that came with your computer.
In line 37 of the program, the constant "12345" is
assigned to the variable "Cow". In the next line, the
variable "Cow" is assigned to the variable "Horse", and the
display procedure is called again. This time, the variable
"Cow" is shorter than the destination, so the system has to
Page 43
Chapter 6 - Arrays, Types, and Constants
compensate for the difference. After it transfers the 5
characters to "Horse", it will place a 0 (zero) in the next
position to indicate the end of the string. The definition
of the string still has 12 places, but there are only 5
places of interest, so the system will consider all places
past the 5th as undefined. This time the system only prints
out 5 characters in the procedure. The list of ASCII
equivalents shows that the other values are still there, the
output routine simply stopped when it came to the 0 in the
sixth position.
Note that the Assign statement may be different for
different compilers because it is not a part of the Modula-2
definition by Niclaus Wirth.
CONCATENATION
Concatenation is simply putting two strings together to
make up one bigger string. Beginning in line 41, two new
string variables are defined, "S1" and "S2", then the two
new variables are concatenated together and assigned to our
old favorite variable named "Horse". The variable "Horse"
should now contain the silly expression "NeatThings", and
when you run the program, you will find that it does. It
also has a 0 in character position 11 now to indicate the
end of the string. Line 47 concatenates "Horse" to "Cow"
and stores the result in "Horse", but since the expression
is now too long, part of it will get truncated and simply
thrown away. Finally, "Cow" is concatenated to "Horse", and
the result stored back into "Horse". This has the effect of
shifting the prior contents of "Horse" right and adding the
characters stored in "Cow" to the beginning. Line 45 is an
example of a string assignment. This is only possible
because they are of the same TYPE. The variable "Cow" has a
different TYPE so can't be assigned to either of these two
variables. Note that the TYPE does not have to start at
zero for this to work.
Note that even though "Horse" was the only variable
used in the calls to "Display", any of the other strings
could have been used also. This is the topic of the fourth
programming exercise below.
Compile and run the program and see if it really does
do all that it should do as described above, keeping in mind
that you may have to modify the file to accommodate your
particular compiler.
PROGRAMMING EXERCISES
Page 44
Chapter 6 - Arrays, Types, and Constants
1. Write a program to store the CARDINAL values 201 to 212
in an array then display them on the monitor.
2. Write a program to store a 10 by 10 array containing
the products of the indices, therefore a multiplication
table. Display the matrix on the monitor.
3. Modify the program in 2 above to include a constant so
that by simply changing the constant, the size of the
matrix and the range of the table will be changed.
4. Modify the program named STRINGEX.MOD to include calls
to "Display" with each of the string variables at the
end of the program.
Page 45